package craky.componentc;

import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Window;
import java.awt.image.BufferedImage;

import javax.swing.JPopupMenu;
import javax.swing.JWindow;
import javax.swing.border.EmptyBorder;

import com.abigdreamer.swing.component.UIUtil;
import com.sun.awt.AWTUtilities;

public class JCPopupMenu extends JPopupMenu {
	private static final long serialVersionUID = -3145232751724445736L;
	private JWindow heavyWeightWindow;
	private boolean buffered;

	public JCPopupMenu() {
		this(null);
	}

	public JCPopupMenu(String label) {
		super(label);
		setUI(new CPopupMenuUI());
		setOpaque(false);
		setBorder(UIUtil.isTranslucencySupported() ? new EmptyBorder(7, 7, 7, 7) : new EmptyBorder(2, 2, 2, 2));
	}

	public void paint(Graphics g) {
		if ((!UIUtil.isTranslucencySupported()) || (!this.buffered)) {
			super.paint(g);
		} else {
			Insets insets = getInsets();
			int x = insets.left;
			int y = insets.top;
			int width = getWidth();
			int height = getHeight();
			int contentWidth = width - insets.left - insets.right;
			int contentHeight = height - insets.top - insets.bottom;
			BufferedImage image = UIUtil.getGraphicsConfiguration(this).createCompatibleImage(width, height, 3);
			BufferedImage contentImage = UIUtil.getGraphicsConfiguration(this).createCompatibleImage(contentWidth, contentHeight, 1);
			Graphics2D g2d = image.createGraphics();
			Graphics2D contentG2d = contentImage.createGraphics();
			contentG2d.translate(-x, -y);
			super.paint(g2d);
			super.paint(contentG2d);
			g2d.dispose();
			contentG2d.dispose();
			g.drawImage(image, 0, 0, this);
			g.drawImage(contentImage, x, y, this);
		}
	}

	public void setVisible(boolean visible) {
		if (visible == isVisible()) {
			return;
		}

		super.setVisible(visible);

		if (UIUtil.isTranslucencySupported()) {
			if ((visible) && (!isOpaque()) && (this.heavyWeightWindow == null)) {
				this.heavyWeightWindow = getHeavyWeightWindow();
			}

			if (this.heavyWeightWindow != null) {
				this.buffered = true;
				AWTUtilities.setWindowOpaque(this.heavyWeightWindow, !visible);
			}
		}
	}

	private JWindow getHeavyWeightWindow() {
		Container c = getParent();

		while ((c != null) && (!(c instanceof Window))) {
			c = c.getParent();
		}

		if ((c != null) && (c.getClass().getName().equalsIgnoreCase("javax.swing.Popup$HeavyWeightWindow"))) {
			return (JWindow) c;
		}

		return null;
	}

	public void addSeparator() {
		add(new Separator());
	}

	@Deprecated
	public void updateUI() {
		setUI(getUI());
	}

	public static class Separator extends JCSeparator {
		private static final long serialVersionUID = 3460403283019419638L;

		public Separator() {
			setBorder(new EmptyBorder(1, 26, 0, 2));
		}
	}
}